package com.quectel.taskserver.job.patrol;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.core.module.grid.dto.GridDto;
import com.quectel.core.module.grid.dto.GridPlanDto;
import com.quectel.core.module.grid.dto.GridPlanGridBindingDto;
import com.quectel.core.module.grid.dto.GridPlanTaskDto;
import com.quectel.core.module.grid.service.*;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.JacksonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static cn.hutool.core.text.CharSequenceUtil.splitTrim;

/**
 * 网格巡更计划生成任务
 * 网格任务和普通巡检任务不同，生成任务时不填充执行人信息
 * 多个网格员可能都能看到任务，根虎网格员类型 来判断是否可以执行
 *
 * @author bob
 * @email bob.yu@quectel.com
 */
@Component
public class GridPatrolGenerateTask implements SimpleJob {
    private static final Logger LOGGER = LoggerFactory.getLogger(GridPatrolGenerateTask.class);

    @DubboReference
    private GridService gridService;
    @DubboReference
    private GridPlanService gridPlanService;
    @DubboReference
    private GridMemberService gridMemberService;
    @DubboReference
    private GridMemberGridBindingService gridMemberGridBindingService;
    @DubboReference
    private GridPlanGridBindingService gridPlanGridBindingService;
    @DubboReference
    private GridPlanTaskService gridPlanTaskService;

    @Override
    public void execute(ShardingContext shardingContext) {
        gridPatrolGenerateTask();
    }


    public void gridPatrolGenerateTask() {
        LOGGER.info("网格巡更任务开始执行... 时间 {} 下面各个机器开始抢占执行",
                DateUtils.getCurrentDateStr(DateUtils.FormatType.COMMON));
        Date nextDate = new Date(System.currentTimeMillis() + 24L * 60 * 60 * 1000);
        String nextDay = new SimpleDateFormat(DateUtils.FormatType.SIMPLE.getType())
                .format(nextDate);
        Date now = new Date();
        //抢占执行生成任务
        LOGGER.info("本次本台机器可以执行生成任务,要生成{}的巡更任务", nextDay);

        List<GridPlanDto> result = new ArrayList<>();
        int pageNo = 1;
        while (true) {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("startTime", nextDay);
            queryMap.put("endTime", nextDay);
            queryMap.put("offset", (pageNo - 1) * 2000);
            queryMap.put("limit", 2000);
            List<GridPlanDto> list = gridPlanService.queryList(queryMap);
            if (list.size() <= 0) {
                break;
            }
            result.addAll(list);
            pageNo++;
        }
        LOGGER.info("要执行巡更计划的条数{}", result.size());
        for (GridPlanDto gridPlanDto : result) {
            if (StringUtils.isNotBlank(gridPlanDto.getWeekPlan())) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(nextDate);
                int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
                if (dayOfWeek - 1 == 0) {
                    dayOfWeek = 7;
                } else {
                    dayOfWeek--;
                }
                List<String> weekPlan = JacksonUtils.parseArray(gridPlanDto.getWeekPlan(), String.class);
                if (!weekPlan.contains(dayOfWeek + "")) {
                    // 日期不满足
                    continue;
                }

                if (StringUtils.isNotBlank(gridPlanDto.getDayPeriodArr())) {
                    List<String> parseArray = JacksonUtils.parseArray(gridPlanDto.getDayPeriodArr(), String.class);
                    for (String period : parseArray) {
                        try {
                            // 针对每个时间段生成
                            Map<String, Object> queryMap = new HashMap<>();
                            queryMap.put(LambdaUtil.getFieldName(GridPlanGridBindingDto::getPlanId), gridPlanDto.getId());
                            List<GridPlanGridBindingDto> gridPlanGridBindingDtos = gridPlanGridBindingService.queryList(queryMap);

                            // 对每个网格生成任务
                            if (CollectionUtils.isEmpty(gridPlanGridBindingDtos)) {
                                break;
                            }

                            for (GridPlanGridBindingDto planGridBinding : gridPlanGridBindingDtos) {
                                Long gridId = planGridBinding.getGridId();
                                GridDto gridDto = gridService.selectCacheById(gridId);
                                if (gridDto == null) {
                                    continue;
                                }

                                // 不填充执行人
                                GridPlanTaskDto taskDto = new GridPlanTaskDto();
                                taskDto.setTenantId(gridPlanDto.getTenantId());
                                taskDto.setVillageId(gridDto.getVillageId());
                                taskDto.setPlanId(gridPlanDto.getId());
                                taskDto.setPlanSnapshot(JacksonUtils.toJsonString(gridPlanDto));
                                taskDto.setGridId(gridId);
                                taskDto.setName(String.format("%s-%s-%s", nextDay, gridPlanDto.getName(), period));
                                taskDto.setDate(nextDay);
                                taskDto.setPeriod(period);
                                List<String> datePeriod = splitTrim(period, "-");
                                List<String> collect = datePeriod.stream()
                                        .map(v -> nextDay + " " + v + ":00")
                                        .collect(Collectors.toList());

                                taskDto.setExecStartTime(DateUtil.parse(collect.get(0), DateUtils.FormatType.COMMON.getType()));
                                taskDto.setExecEndTime(DateUtil.parse(collect.get(1), DateUtils.FormatType.COMMON.getType()));
                                taskDto.setExecStatus((byte) 0);
                                taskDto.setCreateTime(now);
                                gridPlanTaskService.save(taskDto);
                            }

                            // todo 发送消息给网格员

                        } catch (Exception e) {
                            continue;
                        }
                    }
                }
            }
        }
        LOGGER.info("{}网格巡更任务已生成完毕", nextDay);
    }


}























